package rede;

import protocolo.Login;
import protocolo.Mensagem;
import protocolo.Autenticacao;
import protocolo.ExisteLoginException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ConnectException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;

/**
 * @author tiagosn
 */
public class Cliente <T extends MostraDados> implements MostraDados{
    private Socket              socket;
    private ObjectInputStream   entrada;
    private ObjectOutputStream  saida;
    private String              strLogin;
    private T                   ui;
    private Thread              recebeDados;

    /// colocar um tipo generico no construtor e esse tipo deve implementar uma interface pra o cliente imprimir as msg q chegarem(fazer essa interface)
    public Cliente(T ui, Login login, String ipServidor, int porta) throws UnknownHostException, IOException, ClassNotFoundException, ExisteLoginException{
        strLogin = login.getLogin();
        this.ui = ui;
        socket = new Socket(ipServidor, porta);
        entrada = new ObjectInputStream(socket.getInputStream());
        saida = new ObjectOutputStream(socket.getOutputStream());

        Login l = login;
        saida.writeObject(l);
        Autenticacao autenticacao = (Autenticacao)entrada.readObject();

        if(autenticacao.aceita()){
            recebeDados = new Thread(new RecebeDados(this));
            recebeDados.start();
        }else{
            entrada.close();
            saida.close();
            /// criar uma excecao e retornar
            throw new ExisteLoginException(); ///criar um tipo proprio de excecao
        }
    }

    public void enviarMensagem(Mensagem mensagem){
        try {
            saida.writeObject(mensagem);
        } catch (IOException ex) {
            /// tratar
        }
    }

    public void enviarMensagem(String texto){
        enviarMensagem(new Mensagem(strLogin, texto));
    }

    public ObjectInputStream getEntrada(){
        return entrada;
    }

    public void mostrarMensagem(Mensagem mensagem){
        ui.mostrarMensagem(mensagem);
    }

    public void atualizarListaUsuarios(ArrayList<String> logins) {
        ui.atualizarListaUsuarios(logins);
    }
    
    public void terminarConexao(){
        try {
            entrada.close();
            saida.close();
        } catch (IOException ex) {
            /// tratar
        }
    }
}
